package com.example.mp3player;

import java.io.IOException;
import java.util.ArrayList;

import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Binder;
import android.os.IBinder;
import android.widget.RemoteViews;
import android.widget.Toast;

public class Mp3Service extends Service {
	private ArrayList<String> playList;
	private MediaPlayer mp;
	private IBinder mBinder = new Mp3Binder();
	private boolean firstPlay;
	private int songCount;
	private boolean isComplete = false;
	private boolean isLoopingAll = false;
	SharedPreferences shPref;
	AppWidgetManager appWidgetManager;
	int[] allWidgetIds;
	RemoteViews remoteViews;	
	Context ctx;

	@Override
	public void onCreate(){
		playList = new ArrayList<String>();
		mp = new MediaPlayer();
		mp.setLooping(false);
		firstPlay = true;
		songCount = 0;
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId){
		shPref = getSharedPreferences("mp3", MODE_WORLD_READABLE);
		boolean widgetActive = shPref.getBoolean("widget", false);
		ctx = this;
		shPref.registerOnSharedPreferenceChangeListener(mListener);
		appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());
		allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
		
		if(widgetActive){

			for (int widgetId : allWidgetIds) {
				remoteViews = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.widget);

				// Register an onClickListener
				Intent clickIntent = new Intent(this.getApplicationContext(), Mp3Widget.class);

				if(!playList.isEmpty() && mp != null){
					remoteViews.setTextViewText(R.id.tv, getSongName());
				}
				else{
					Toast.makeText(this, "Playlist is empty", Toast.LENGTH_SHORT).show();
				}
				
				// Update the widget
				clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
				clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
				PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
				remoteViews.setOnClickPendingIntent(R.id.widget_update, pendingIntent);
				
				//Open the activity
				Intent openActivity = new Intent(this.getApplicationContext(), Mp3Activity.class);
				openActivity.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
				PendingIntent pendingOpenActivity = PendingIntent.getActivity(getApplicationContext(), 0, openActivity, Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
				remoteViews.setOnClickPendingIntent(R.id.widgetLayout, pendingOpenActivity);

				appWidgetManager.updateAppWidget(widgetId, remoteViews);
			}
			stopSelf();
		}
	      
	    super.onStartCommand(intent, flags, startId);
	    return Service.START_STICKY;
	}
	
	public OnSharedPreferenceChangeListener mListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
		public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {  
			remoteViews = new RemoteViews(getApplicationContext().getPackageName(),R.layout.widget);
			for(int widgetID : allWidgetIds){
				if(!playList.isEmpty()){
					remoteViews.setTextViewText(R.id.tv, getSongName());
				}
				appWidgetManager.updateAppWidget(widgetID, remoteViews);
			}
		}
	};

	
	//--------------------------------------------------------//
	/*					Button Methods						*/
	//--------------------------------------------------------//
	
	public void play(){	
		/*If firstPlay set to first song in list	*/
		if(firstPlay && !playList.isEmpty()){
			firstPlay = false;
			try {
				mp.setDataSource(playList.get(0));
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				mp.prepare();
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			mp.start();
		}
		/*	If not firstplay and mediaplayer not playing and playlist is not empty	*/
		else if(!mp.isPlaying() && !playList.isEmpty()){
			mp.start();	//start mediaplayer
		}
		else if(mp.isPlaying()){
			Toast.makeText(this, "Already playing", Toast.LENGTH_SHORT).show();
		}
		else{
			Toast.makeText(this, "Playlist is empty, please choose a mp3-file", Toast.LENGTH_SHORT).show();
		}

		mp.setOnCompletionListener(onCompletionListener);
	}
		
	/*	Pause if playing	*/
	public void pause(){
		if(mp.isPlaying()){
			mp.pause();
		}
	}

	/*	Get next song	*/
	public void next(){
		boolean isLoop = mp.isLooping();
		songCount++;
		if(mp.isPlaying()){
			mp.stop();
		}
		mp.reset();
		mp.setLooping(isLoop);
		/*	if not last song in list get next	*/
		if(songCount < playList.size() && !playList.isEmpty()){
			try {
				mp.setDataSource(playList.get(songCount));
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		/*	if last song get first */
		else if(!playList.isEmpty()){
			songCount = 0;
			try {
				mp.setDataSource(playList.get(songCount));
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			mp.prepare();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if(!playList.isEmpty()){
			mp.start();
		}
		else{
			Toast.makeText(this, "Playlist is empty, add song to play", Toast.LENGTH_SHORT).show();
		}
	}

	public void prev(){
		boolean isLoop = mp.isLooping();
		songCount--;
		if(mp.isPlaying()){
			mp.stop();
		}
		mp.reset();
		mp.setLooping(isLoop);
		/*	if not first song get previous	*/
		if(songCount >= 0 && !playList.isEmpty()){
			try {
				mp.setDataSource(playList.get(songCount));
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		/*	if first song get last	*/
		else if(!playList.isEmpty()){
			songCount = playList.size()-1;
			try {
				mp.setDataSource(playList.get(songCount));
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			mp.prepare();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if(!playList.isEmpty()){
			mp.start();
		}
		else{
			Toast.makeText(this, "Playlist is empty, add song to play", Toast.LENGTH_SHORT).show();
		}
	}
	
	public void changeSong(int pos){
		songCount = pos;
		boolean loopTmp = mp.isLooping();
		if(mp.isPlaying()){
			mp.stop();
		}
		mp.reset();
		mp.setLooping(loopTmp);
		try {
			mp.setDataSource(playList.get(songCount));
			mp.prepare();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		mp.setOnCompletionListener(onCompletionListener);
		mp.start();
	}
	
	/*	If song ended, get next song in list! If it is last song get first song in list */
	OnCompletionListener onCompletionListener = new MediaPlayer.OnCompletionListener() {
		public void onCompletion(MediaPlayer mp) {
			if(!playListIsEmpty() && !mp.isLooping()){
				songCount++;
			}
			mp.stop();
			mp.reset();
			if(songCount < playList.size() && !playList.isEmpty()){
				try {
					mp.setDataSource(playList.get(songCount));
					mp.prepare();
				} catch (IllegalStateException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				mp.start();
			}
			else if(!playList.isEmpty()){
				songCount = 0;
				try {
					mp.setDataSource(playList.get(songCount));
					mp.prepare();
				} catch (IllegalStateException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
				if(isLoopingAll){
					mp.start();
				}
				else{
					isComplete = true;
				}
			}
		}
	};

	//--------------------------------------------------------//
	/*					GETTERS & SETTERS					*/
	//--------------------------------------------------------//
	
	
	/*	add song to playList	*/
	public void addSong(String path){
		playList.add(path);
	}

	/*	return true if playing	*/
	public boolean isPlaying(){
		if(mp != null && mp.isPlaying()){
			return true;
		}
		else{
			return false;
		}
	}

	/*	return true if playlist is empty	*/
	public boolean playListIsEmpty(){
		if(playList != null){
			return false;
		}
		else{
			return true;
		}
	}

	/*	Get id3 tags from mp3-file else send file-name*/
	public String getSongName(){
		MediaMetadataRetriever mmr = new MediaMetadataRetriever();
		if(!playList.isEmpty() || playList.size() >= 1){
			mmr.setDataSource(playList.get(songCount));
			if(mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST).isEmpty() 
					|| mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE).isEmpty()){
				String[] tmp = playList.get(songCount).split("/");
				String[] file = tmp[tmp.length-1].split(".");
				String fileName = file[0];
				return fileName;
			}
			else{
				String artist = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
				String song = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
				String tmp = artist + " - " + song;
				return tmp;
			}
		}
		return "";
	}

	/*	return song duration in minutes and seconds	*/
	public String getSongLength(){
		int minutes = (mp.getDuration()/1000)/60;
		int sec = mp.getDuration()/1000%60;
		String duration = minutes + ":" + sec;
		return duration;
	}

	/*	return time left in minutes and seconds	*/
	public String getTimePassed(){
		int minutes = ((mp.getDuration()-mp.getCurrentPosition())/1000)/60;
		int sec = (mp.getDuration()-mp.getCurrentPosition())/1000%60;
		String timePassed = minutes + ":" + sec;
		return timePassed;
	}

	/*	return song duration in ms	*/
	public int getDuration(){
		return mp.getDuration();
	}
	
	public boolean getFirstPlay(){
		if(firstPlay){
			return true;
		}
		else{
			return false;
		}
	}

	/*	return current position in song in ms	*/
	public int getCurrentPosition(){
		return mp.getCurrentPosition();
	}

	public MediaPlayer getMediaPlayer(){
		return mp;
	}
	
	public ArrayList<String> getPlaylist(){
		return playList;
	}
	
	public int getSongCount(){
		return songCount;
	}
	
	public boolean getIsComplete(){
		return isComplete;
	}
	
	public boolean getLoopAll(){
		return isLoopingAll;
	}
	
	public void setIsComplete(boolean complete){
		this.isComplete = complete;
	}
	
	public void setLoopAll(boolean loopAll){
		this.isLoopingAll = loopAll;
	}
	
	public void setSongCount(int subtract){
		songCount = songCount-subtract;
	}

	//--------------------------------------------------------//
	/*						Binders							*/
	//--------------------------------------------------------//
	
	
	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}


	public class Mp3Binder extends Binder {
		Mp3Service getService() {
			return Mp3Service.this;
		}
	}
}
